package com.zzw.algorithm;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 〈〉<br>
 * 〈〉
 *
 * @author zzw
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本]（可选）
 */
public class ManyNodeTree {

    /** 树根*/
    private ManyTreeNode root;

    /**
     * 构造函数
     */
    public ManyNodeTree(String nodeId) {
        root = new ManyTreeNode(new TreeNode(nodeId));
    }

    /**
     * 生成一颗多叉树，根节点为root
     *
     * @param treeNodes 生成多叉树的节点集合
     * @return ManyNodeTree
     */
    public ManyNodeTree createTree(List<TreeNode> treeNodes) {

        if(treeNodes == null || treeNodes.size() < 0) {
            return null;
        }

        //将所有节点添加到多叉树中
        for(TreeNode treeNode : treeNodes) {

            if(treeNode.getParentId().equals(this.getRoot().getData().getNodeId())) {
                //向根添加一个节点
                this.getRoot().getChildList().add(new ManyTreeNode(treeNode));
            }
            else {
                addChild(this.getRoot(), treeNode);
            }
        }

        return this;
    }

    public ManyNodeTree createTree2(List<String> list) {

        if(list == null || list.size() < 0) {
            return null;
        }

        //将所有节点添加到多叉树中
        for(String s : list) {
            if ((s.length() - this.getRoot().getData().getNodeId().length()) == 2){
                List<ManyTreeNode> childList = this.getRoot().getChildList();
                if(childList == null || childList.size() == 0){
                    TreeNode treeNode = new TreeNode(s, this.getRoot().getData().getNodeId());
                    this.getRoot().getChildList().add(new ManyTreeNode(treeNode));
                }
                else {
                    //String[] child = s.split("\\.");
                    //String[] split = childList.get(childList.size() - 1).getData().getNodeId().split("\\.");
                    //if ((Integer.parseInt(split[split.length - 1]) - Integer.parseInt(child[child.length - 1])) < 0) {
                    boolean flag = false;
                    for(ManyTreeNode node:this.getRoot().getChildList()){
                        if(node.getData().getNodeId().contains(s)) {
                            flag = true;
                        }
                    }
                    if(!flag){
                        TreeNode treeNode = new TreeNode(s, this.getRoot().getData().getNodeId());
                        this.getRoot().getChildList().add(new ManyTreeNode(treeNode));
                    }
                    //}
                }
            }
            else {
                addChild2(this.getRoot(),s);
            }
        }

        return this;
    }


    public void addChild2(ManyTreeNode manyTreeNode, String child) {
        TreeNode treeNode = null;
        for(ManyTreeNode item : manyTreeNode.getChildList()) {
            if (child.contains(item.getData().getNodeId())){
                List<ManyTreeNode> childList = item.getChildList();
                if(childList == null || childList.size() == 0){
                    treeNode = new TreeNode(child,item.getData().getNodeId());
                    item.getChildList().add(new ManyTreeNode(treeNode));
                }
                else {
                   /* String[] childS = child.split("\\.");
                    String[] split = childList.get(childList.size() - 1).getData().getNodeId().split("\\.");
                    if ((Integer.parseInt(split[split.length - 1]) - Integer.parseInt(childS[childS.length - 1])) < 0) {*/
                    boolean flag = false;
                    for(ManyTreeNode node:item.getChildList()){
                        if(node.getData().getNodeId().contains(child)) {
                            flag = true;
                        }
                    }
                    if(!flag){
                        treeNode = new TreeNode(child, item.getData().getNodeId());
                        item.getChildList().add(new ManyTreeNode(treeNode));
                        /*Collections.sort(item.getChildList(), new Comparator<ManyTreeNode>() {
                            @Override
                            public int compare(ManyTreeNode o1, ManyTreeNode o2) {
                                String[] split = o1.getData().getNodeId().split("\\.");
                                String[] split2 = o2.getData().getNodeId().split("\\.");
                                if((Integer.parseInt(split[split.length - 1]) - Integer.parseInt(split2[split2.length - 1])) < 0){
                                    return -1;
                                }
                                return 1;
                            }
                        });*/
                    }
                    //}
                }
            }
            else {
                if(item.getChildList() != null && item.getChildList().size() > 0) {
                    addChild2(item, child);
                }
            }
        }
    }

    /**
     * 向指定多叉树节点添加子节点
     *
     * @param manyTreeNode 多叉树节点
     * @param child 节点
     */
    public void addChild(ManyTreeNode manyTreeNode, TreeNode child) {

        for(ManyTreeNode item : manyTreeNode.getChildList()) {
            if(item.getData().getNodeId().equals(child.getParentId())) {
                //找到对应的父亲
                item.getChildList().add(new ManyTreeNode(child));
                break;
            }
            else {
                if(item.getChildList() != null && item.getChildList().size() > 0) {
                    addChild(item, child);
                }
            }
        }
    }

    /**
     * 遍历多叉树
     *
     * @param manyTreeNode 多叉树节点
     * @return
     */
    public String iteratorTree(ManyTreeNode manyTreeNode) {

        StringBuilder buffer = new StringBuilder();
        buffer.append("\n");

        if(manyTreeNode != null) {

            Collections.sort(manyTreeNode.getChildList(), new Comparator<ManyTreeNode>() {
                @Override
                public int compare(ManyTreeNode o1, ManyTreeNode o2) {
                    String[] split = o1.getData().getNodeId().split("\\.");
                    String[] split2 = o2.getData().getNodeId().split("\\.");
                    if((Integer.parseInt(split[split.length - 1]) - Integer.parseInt(split2[split2.length - 1])) < 0){
                        return -1;
                    }
                    return 1;
                }
            });

            for (ManyTreeNode index : manyTreeNode.getChildList()) {

                buffer.append(index.getData().getNodeId()+ ",");

                if (index.getChildList() != null && index.getChildList().size() > 0 ) {
                    buffer.append(iteratorTree(index));
                }
            }
        }

        buffer.append("\n");

        return buffer.toString();
    }

    public ManyTreeNode getRoot() {
        return root;
    }

    public void setRoot(ManyTreeNode root) {
        this.root = root;
    }

    public static void main(String[] args) throws JsonProcessingException {

        List<TreeNode> treeNodes = new ArrayList<TreeNode>();

        List<String> list = new ArrayList<>();
        list.add("1.0");
        list.add("1.0.0");
        list.add("1.0.1");
        list.add("1.0.2");
        list.add("1.0.3.2");
        list.add("1.0.3.3");
        list.add("1.0.3.4");
        list.add("1.0.1.1");
        list.add("1.0.4.2");
        list.add("1.0.4.3");
        list.add("1.0.4.4");
        list.add("1.0.4.5");
        list.add("1.0.4.6");
        list.add("1.0.4.7");
        list.add("1.0.4.8");
        list.add("1.0.0.2");
        list.add("1.0.0.1");
        list.add("1.0.0.2");
        list.add("1.0.0.4");
        list.add("1.0.1.1");
        list.add("1.0.1.2");
        list.add("1.0.1.3");
        list.add("1.0.3");
        list.add("1.0.4");
        list.add("1.0.1.4");
        list.add("1.0.2.1");
        list.add("1.0.2.2");
        list.add("1.0.2.3");
        list.add("1.0.2.4");
        list.add("1.0.3.1");

        int index = 0;

        //先找到根节点
        for (int i = 0;i < list.size();i++){
            if (list.get(i).length() < list.get(index).length()){
                index = i;
            }
        }

        ManyNodeTree tree = new ManyNodeTree(list.get(index));
        list.remove(index);
        tree.createTree2(list);

        System.out.println(tree.iteratorTree(tree.getRoot()));

        String s = new ObjectMapper().writeValueAsString(tree);

        System.out.println(s);
    }
}
